var submitServer = 'http://10.8.1.100:30080';

var data = {
    "desc": "",
    "requiredLogin": false,
    "loginUrl": null,
    "hasAjax": false,
    "isSpread": false,
    "maxAmt": 1,
    "maxHier": -1,
    "testurl": location.href,
    "props-ext": {}
}

var start = {
    "desc": {
        "type": "text",
        "info": "描述"
    },
    "requiredLogin": {
        "type": "boolean",
        "info": "是否需要登录"
    },
    "loginUrl": {
        "type": "text",
        "info": "登录页面地址"
    },
    "hasAjax": {
        "type": "boolean",
        "info": "是否有ajax"
    },
    "isSpread": {
        "type": "boolean",
        "info": "是否扩散任务"
    },
    "maxAmt": {
        "type": "text",
        "info": "maxAmt"
    },
    "maxHier": {
        "type": "text",
        "info": "maxHier"
    },
    "testurl": {
        "type": "text",
        "info": "测试地址"
    },
    "page": {
        "type": "parser",
        "state": "-1",
        "info": "分页"
    },
    "root": {
        "type": "parser",
        "state": "-1",
        "info": "根"
    },
    "props": {
        "type": "props",
        "info": "抓取的东西"
    }
}
var opts = {
    DOM: {
        "info": "不需要填东西",
        "attr": false
    },
    TEXT: {
        "info": "不需要填东西",
        "attr": false
    },
    HTML: {
        "info": "不需要填东西",
        "attr": false
    },
    ATTR: {
        "info": "填元素的属性",
        "attr": true
    },
    URL: {
        "info": "不需要填东西",
        "attr": false
    },
    CONSTB: {
        "info": "在前面拼接的字符串",
        "attr": true
    },
    CONSTE: {
        "info": "在后面拼接的字符串",
        "attr": true
    },
    REGEXP: {
        "info": "正则表达式 字符串形式",
        "attr": true
    },
    REPLACE: {
        "info": "不需要填东西",
        "attr": false
    },
    SUBSTR: {
        "info": "截取字符串 int",
        "attr": true
    },
    CLICK: {
        "info": "不需要填东西",
        "attr": false
    },
    SCROLL: {
        "info": "滚动到哪,STEP | BOTTOM | 100VH（100表示1屏）",
        "attr": true
    },
    WAIT: {
        "info": "等待多长时间 int",
        "attr": true
    },
    ARTICLE: {
        "info": "值不为空结果的链接会被替换",
        "attr": false
    },
    ABS: {
        "info": "不需要填东西",
        "attr": false
    },
    RETIFNULL: {
        "info": "是否需要验证上一步值不为空",
        "attr": false
    },
    REMOVE: {
        "info": "删除的节点",
        "attr": true
    }
}



////////
var app = {
    init: function(data) {
        $('#main').html('');
        var that = this;
        this.data = data;
        this.makeParser($('#main'), that.data, "抓取实例", 1);
    },
    initEvent: function() {
        var that = this;
        this.initTip();
        this.loadFromTxt();
        this.removeHistory();
        this.loadHistory();
        this.initHistory();
        this.saveParser();
        this.addRoot();
        this.addPage();
        this.submitParser();
        this.toggle();
        this.addParser();
        this.addAction();
        this.removeSelector();
        this.addSelector();
        this.removeParser();
        this.removeAction();
    },
    loadFromTxt: function() {
        var that = this;
        $('body').on('click', '.loadFromTxt', function() {
            var data = JSON.parse($('#txt').val());
            that.init(data);
        });

    },
    removeHistory: function() {
        var that = this;
        $('body').on('click', '.history .remove', function() {
            var key = $(this).parent('.item').find('p').text();
            var pawebconfig = localStorage.pawebconfig;
            var data = JSON.parse(pawebconfig);
            delete data[key];
            localStorage.pawebconfig = JSON.stringify(data);
            $(this).parent('.item').remove();
        })
    },
    loadHistory: function() {
        var that = this;
        $('body').on('click', '.history .load', function() {
            var key = $(this).parent('.item').find('p').text();
            var pawebconfig = localStorage.pawebconfig;
            var data = JSON.parse(pawebconfig)[key];
            that.init(data);
        })
    },
    initHistory: function() {
        var pawebconfig = localStorage.pawebconfig;
        if (!pawebconfig) return;
        $('.history').empty();
        for (var pars in JSON.parse(pawebconfig)) {
            $('.history').append('<div class="item"><p>' + pars + '</p><a href="javascript:;" class="load">载入</a><a href="javascript:;" class="remove">移除</a></div>');
        }
    },
    makeParser: function(parentNode, parser, info, base) {
        if (info == 'url') return;
        var that = this;
        var $par = $('.parserTPL .parserWrap').clone();
        if (info == '根节点及页面初始化' || info == '分页配置' || base) {
            $par.find('.props-ext').remove();
        }

        if (info == '根节点及页面初始化' || info == '分页配置') {
            //设置root 或 分页时 没有 爬取属性和 根节点 分页
            $par.find('.props').remove();
            $par.find('.root').remove();
            $par.find('.page').remove();
            parentNode.find('> .addRoot').hide();
            parentNode.find('> .addPage').hide();
        }
        //base
        if (base) {
            var $info = $('.infoTPL .infoWrap').clone();
            $par.find('>.name').after($info);
            $par.find('>.name .removeParser').remove();
            $par.find('.addSelector').remove();
            that.checkBaseInfo($par.find('> .infoWrap'), that.data);
            $par.find('>.props >.propsList').append('<a href="javascript:;" class="addParser">增加爬取条目</a>');
        } else {
            // $par.find('.props').remove();
            that.checkInfo($par.find('> .props-ext'), that.data['props-ext'][info])
            $par.find('>.props >.propsList').append('<a href="javascript:;" class="addParser">增加子爬取条目</a>');
        }

        if (parentNode.find('>.addParser').size()) {
            parentNode.find('>.addParser').before($par);
        } else {
            parentNode.append($par);
        }
        $par.find('>.name span').text(info)
        if (parser.selectors) {
            $.each(parser.selectors, function(i, val) {
                that.makeSelector($par.find('.selectorList'), val);
            });
        }
        if (parser.root) {
            that.makeParser($par.find('>.root'), parser.root, '根节点及页面初始化');
        } else {
            // if (base) {
            $par.find('>.root').html('<a href="javascript:;" class="addRoot">增加root</a>');
            // }
        }
        if (parser.page) {
            that.makeParser($par.find('>.page'), parser.page, '分页配置');
        } else {
             if (base) {
            $par.find('>.page').html('<a href="javascript:;" class="addPage">增加page</a>');
             }
        }
        if (parser.props) {
            for (var prop in parser.props) {
                that.makeParser($par.find('>.props >.propsList'), parser.props[prop][0], prop);
            }
        }
    },
    addRoot: function() {
        var that = this;
        $('body').on('click', '.addRoot', function() {
            that.makeParser($(this).closest('.root'), {}, '根节点及页面初始化');
        })
    },
    addPage: function() {
        var that = this;
        $('body').on('click', '.addPage', function() {
            that.makeParser($(this).closest('.page'), {}, '分页配置');
        })
    },
    checkBaseInfo: function(el, data) {
        el.find('[name=desc]').val(data.desc || '');
        el.find('[name=testurl]').val(data.testurl || '');
        el.find('[name=loginUrl]').val(data.loginUrl || '');
        el.find('[name=maxAmt]').val(data.maxAmt || -1);
        if (data.requiredLogin) {
            el.find('[name=requiredLogin]').attr('checked', true);
        }
        if (data.hasAjax) {
            el.find('[name=hasAjax]').attr('checked', true);
        }
        if (data.isSpread) {
            el.find('[name=isSpread]').attr('checked', true);
        }

    },
    checkInfo: function(el, data) {
        // that.checkInfo( $par.find('> .props-ext'),parser['props-ext'][info] )
        if (!data) return;
        el.find('[name=desc]').val(data.desc);
        if (data.required) {
            el.find('[name=required]').attr('checked', true);
        }
        if (data.isSpread) {
            el.find('[name=isSpread]').attr('checked', true);
        }
    },
    makeSelector: function(parentNode, selector) {
        var that = this;
        var $sel = $('.selectorTPL .selector').clone();
        parentNode.append($sel);
        $sel.find('[name="select"]').val(selector.select);
        //next
        that.makeAction($sel.find('[role=next] .value'), selector.next);
        //action
        that.makeAction($sel.find('[role=action] .value'), selector.action);
    },
    makeAction: function(parentNode, action) {
        var that = this;
        if (!action) {
            parentNode.append('<a href="javascript:;" class="addAction">Add</a>');
            return;
        }
        parentNode.find('>.addAction').remove();
        var $act = $('.actionTPL .action_item').clone();
        parentNode.append($act);

        $act.find('[name=attr]').val(action.attr);
        $act.find('.select option[value="' + action.opt + '"]').attr('selected', true);
        if (action.next) {
            that.makeAction($act.find('[role=next] .value'), action.next);
        } else {
            $act.find('[role=next] .value').append('<a href="javascript:;" class="addAction">Add</a>');
        }
    },
    initTip: function() {
        var that = this;
        $('body').on('change', 'select[data-name="opt"]', function() {
            var info = opts[$(this).val()].info;
            var roleIndex = $(this).attr('rel');
            $(this).closest('.action_item').find('>[role=attr] .value [name=attr]').val('').attr('placeholder', info);
            that.initNext($(this).closest('.action_item').find('>[role=next] > .value'));
        });
    },
    initNext: function(nextNode) {
        nextNode.html('<a href="javascript:;" class="addAction">Add</a>');
    },
    removeAction: function() {
        var that = this;
        $('body').on('click', '.removeAction', function() {
            var nextNode = $(this).closest('.value');
            that.initNext(nextNode);
        });
    },
    addAction: function() {
        var that = this;
        $('body').on('click', '.addAction', function() {
            var thisAttr = $(this).closest('.action_item').find('>[role=attr] [name=attr]');
            var opt = $(this).closest('.action_item').find('>[role=opt] .select').val();
            if (opt) {
                var required = opts[opt].attr;
                if (required && thisAttr.val() === '') {
                    alert('当前action的attr值不能为空');
                    return;
                }
            }
            var action = {
                "attr": null,
                "next": null,
                "opt": "DOM"
            };
            var parentNode = $(this).parent('.value');
            that.makeAction(parentNode, action);
        });
    },
    removeSelector: function() {
        var that = this;
        $('body').on('click', '.removeSelector', function() {
            $(this).closest('.selector').remove();
        });
    },
    addSelector: function() {
        var that = this;
        $('body').on('click', '.addSelector', function() {
            that.makeSelector($(this).prev('.selectorList'), {
                "action": null,
                "next": null,
                "select": ""
            })
        });
    },
    toggle: function() {
        $('body').on('click', '.parserWrap .name .toggle', function() {
            $(this).parents('.name').nextAll('*').toggle();
        });
    },
    removeParser: function() {
        $('body').on('click', '.removeParser', function() {
            if( $(this).prev('span').html() == '根节点及页面初始化' ){
                $(this).closest('.root').find('>.addRoot').show();
            }
            if( $(this).prev('span').html() == '分页配置' ){
                $(this).closest('.page').find('>.addPage').show();
            }
            $(this).closest('.parserWrap').remove();
        });
    },
    addParser: function() {
        var that = this;
        $('body').on('click', '.addParser', function() {
            var name = prompt("请输入此爬取项的key", "");
            if (!name) return;
            that.makeParser($(this).closest('.propsList'), {}, name)
        });
    },
    submitParser: function() {
        var that = this;
        $('body').on('click', '.submitParser', function() {
            that.createParser(function(data) {
                $('#result').html(JSON.stringify(data));
                console.log( data );
                $.ajax({
                    url:submitServer + '/rule/submit',
                    data : JSON.stringify(data),
                    type:'POST',
                    dataType : 'json',
                    contentType: 'application/json',
                    success:function(res){
                        console.log(res);
                        document.title = res.result;
                    },
                    error:function(){

                    }
                })
            })
        });
    },
    saveParser: function() {
        var that = this;
        $('body').on('click', '.saveParser', function() {
            var key = $('#main > .parserWrap > .infoWrap [name="desc"]').val();
            if (!key) {
                return;
            }
            localStorage.pawebconfig = localStorage.pawebconfig || JSON.stringify({});
            var data = JSON.parse(localStorage.pawebconfig);

            that.createParser(function(res) {
                data[key] = res;
                localStorage.pawebconfig = JSON.stringify(data);
                that.initHistory();
            })
        });
    },
    createParser: function(callback) {
        var result = {
            "desc": "",
            "requiredLogin": false,
            "loginUrl": null,
            "hasAjax": false,
            "isSpread": false,
            "maxAmt": 1,
            "maxHier": -1,
            "testurl": location.href,
            "root": null,
            "page": null,
            "props": {
                "url": [{
                    "selectors": [{
                        "action": {
                            "attr": null,
                            "next": null,
                            "opt": "URL"
                        },
                        "next": null,
                        "select": ""
                    }]
                }]
            },
            "props-ext": {
                "url": {
                    "desc": "当前页地址",
                    "required": true,
                    "isSpread": false,
                    "regexp": null
                }
            }
        }
        var parserWrap = $('#main > .parserWrap');
        var info = parserWrap.find('.infoWrap');
        result.desc = info.find('[name=desc]').val();
        result.requiredLogin = info.find('[name=requiredLogin]').is(':checked');
        result.loginUrl = info.find('[name=loginUrl]').val();
        result.hasAjax = info.find('[name=hasAjax]').is(':checked');
        result.isSpread = info.find('[name=isSpread]').is(':checked');
        result.maxAmt = parseInt(info.find('[name=maxAmt]').val()) || -1;
        result.testurl = info.find('[name=testurl]').val();


        enCodeParser(null, result, $('#main > .parserWrap'));

        function enCodeParser(key, objBase, baseRoot, isProp) {
            if (!baseRoot || !baseRoot.size()) {
                objBase[key] = null;
            } else if (key) {
                // props 和 root page 的parser结构不同
                if (isProp) {
                    objBase[key] = [];
                    objBase[key][0] = objBase[key][0] || {};
                    objBase[key][0].selectors = objBase[key][0].selectors || [];
                    var selectorList = baseRoot.find(' > .selectorList > .selector');
                    if (!selectorList.size()) {
                        objBase[key][0] = null;
                    } else {
                        selectorList.each(function(i, el) {
                            objBase[key][0].selectors.push(enCodeSelector($(el)))
                        })
                    }
                    if (baseRoot.find('> .root  > .parserWrap').size()) {
                        objBase[key][0] = {};
                        enCodeParser('root', objBase[key][0], baseRoot.find('> .root  > .parserWrap'));
                    }
                    if (baseRoot.find('> .page  > .parserWrap').size()) {
                        objBase[key][0] = {};
                        enCodeParser('page', objBase[key][0], baseRoot.find('> .page  > .parserWrap'));
                    }
                } else {
                    objBase[key] = objBase[key] || {};
                    objBase[key].selectors = objBase[key].selectors || [];
                    var selectorList = baseRoot.find(' > .selectorList > .selector');
                    if (!selectorList.size()) {
                        objBase[key] = null;
                    } else {
                        selectorList.each(function(i, el) {
                            objBase[key].selectors.push(enCodeSelector($(el)))
                        })
                    }
                    if (baseRoot.find('> .root  > .parserWrap').size()) {
                        enCodeParser('root', objBase, baseRoot.find('> .root  > .parserWrap'));
                    }
                    if (baseRoot.find('> .page  > .parserWrap').size()) {
                        enCodeParser('page', objBase, baseRoot.find('> .page  > .parserWrap'));
                    }
                }
            } else {
                if (baseRoot.find('> .root  > .parserWrap').size()) {
                    enCodeParser('root', objBase, baseRoot.find('> .root  > .parserWrap'));
                }
                if (baseRoot.find('> .page  > .parserWrap').size()) {
                    enCodeParser('page', objBase, baseRoot.find('> .page  > .parserWrap'));
                }
            }
            // console.log(baseRoot ,objBase);

            if (baseRoot.find('> .props > .propsList > .parserWrap').size()) {
                baseRoot.find('> .props > .propsList > .parserWrap').each(function(i, el) {
                    // 确定是深层prop  还是基层prop

                    var keys = $(el).find('> .name span').text();
                    if (isProp) {
                        objBase[key] = objBase[key] || [];
                        objBase[key][0].props = objBase[key][0].props || {};
                        enCodeParser(keys, objBase[key][0].props, $(el), 1);
                    } else {
                        objBase.props[keys] = objBase.props[keys] || {};
                        enCodeParser(keys, objBase.props, $(el), 1);
                    }

                    var ext = enCodePropsExt($(el));
                    if (!ext) {
                        alert('描述不能为空');
                        return;
                    }
                    result['props-ext'][keys] = ext;
                })
            }
        }

        function enCodePropsExt(prop) {
                var info = prop.find('> .props-ext');
                var data = {};
                data.desc = info.find('[name=desc]').val() || '  ';
                if (data.desc == '') {
                    return false;
                }
                data.required = info.find('[name=required]').is(':checked');
                data.isSpread = info.find('[name=isSpread]').is(':checked');
                data.regexp = null;
                return data;
            }
            /**
             * [enCodeSelector description]
             * @param  {[type]} selector [description]
             * @return {[object]}          [selector]
             */
        function enCodeSelector(selector) {
            var result = {};
            result.select = selector.find(' [name=select] ').val();
            var actionItem = selector.find(' > dd > [role=action] > .value > .action_item ');
            if (actionItem.size()) {
                result.action = {};
                enCodeAction(result.action, actionItem)
            } else {
                result.action = null;
            }
            return result;
        }

        /**
         * [enCodeAction description]
         * @param  {[type]} objBase    [description]
         * @param  {[type]} actionRoot [description]
         * @return {[object]}            [action]
         */
        function enCodeAction(objBase, actionRoot) {
            objBase.attr = actionRoot.find('> [role=attr] [name=attr]').val() || null;
            objBase.opt = actionRoot.find('> [role=opt] [name=opt]').val() || null;
            var nextActionItem = actionRoot.find('> [role=next] > .nextValue > .action_item');
            if (nextActionItem.size()) {
                objBase.next = {};
                enCodeAction(objBase.next, nextActionItem);
            } else {
                objBase.next = null;
            }
        }
        console.log(result);
        callback(result);
    }
}
app.init(data);
app.initEvent();